package ro.fortech.peaa.service.impl;

import java.util.Iterator;
import java.util.List;

import ro.fortech.peaa.domain.Employee;
import ro.fortech.peaa.repository.api.IEmployeeMapper;
import ro.fortech.peaa.service.api.IEmployeeIdentityMap;

public class EmployeeManagerWithIdentityMap extends EmployeeManager {
	private IEmployeeIdentityMap employeeIdentityMap;
	private IEmployeeMapper employeeMapper;

	public void setEmployeeIdentityMap(IEmployeeIdentityMap employeeIdentityMap) {
		this.employeeIdentityMap = employeeIdentityMap;
	}

	public void setEmployeeMapper(IEmployeeMapper employeeMapper) {
		this.employeeMapper = employeeMapper;
	}
	
	public void deleteEmployee(Employee employee) throws Exception {
		employeeMapper.delete(employee);
		employeeIdentityMap.remove(employee);
	}
	
	public Employee find(Integer id) throws Exception {
		Employee employee = employeeIdentityMap.get(id);
		if (employee == null) {
			// Employee with id could not be found in IM, so search in database
			employee = employeeMapper.find(id);
			if (employee != null) {
				employeeIdentityMap.put(employee); 
			}
		}
		return employee;
	}

	public List<Employee> findAll() throws Exception {
		List<Employee> employees = null;
		/*
		 *  Check if number of employees in database is equal to number of
		 *  employees from Identity Map 
		 */
		int dbUsers = employeeMapper.count().intValue();
		int mapUsers = employeeIdentityMap.size().intValue();
		if (dbUsers != mapUsers) {
			employees =  employeeMapper.findAll();
			/*
			 * Refresh map
			 */
			for (Iterator<Employee> it = employees.iterator(); it.hasNext();) {
				Employee employee = (Employee) it.next();
				employeeIdentityMap.put(employee);
			}
		} else {
			employees = employeeIdentityMap.getAll();
		}
		
		return employees;
	}

	public void insertEmployee(Employee employee) throws Exception {
		employeeMapper.insert(employee);
		employeeIdentityMap.put(employee);
	}

	public void updateEmployee(Employee employee) throws Exception {
		employeeMapper.update(employee);
		employeeIdentityMap.put(employee);
	}
	
	public Double getAverageSalary() throws Exception {
		List<Employee> employees = this.findAll();
		Double sum = new Double(0);
		for (Iterator<Employee> it = employees.iterator(); it.hasNext();) {
			sum += ((Employee) it.next()).getSalary();
		}
		return sum / employees.size();
	}
}
